package com.meida.module.bus.provider.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 图片合成工具类
 */
public class ImageSyntheticUtil {

    /**
     * 画布初始化网络图片
     *
     * @param path   路径
     * @param with   背景图宽度
     * @param height 背景图高度
     * @return canvas
     * @throws Exception
     */
    public static BufferedImage drawInitByNetworkPath(String path, int with, int height) throws Exception {
        URL url = new URL(path);
        BufferedImage canvas = ImageIO.read(url);
        canvas = changeSize(canvas, with, height);
        return canvas;
    }

    /**
     * 画布初始化本地图片
     *
     * @param path   路径
     * @param with   背景图宽度
     * @param height 背景图高度
     * @return canvas
     * @throws Exception
     */
    public static BufferedImage drawInitByLoaclPath(String path, int with, int height) throws Exception {
        File file = new File(path);
        BufferedImage canvas = drawInitByFile(file, with, height);
        return canvas;
    }

    /**
     * 画布初始化输入流
     *
     * @param file   文件
     * @param with   背景图宽度
     * @param height 背景图高度
     * @return canvas
     * @throws Exception
     */
    public static BufferedImage drawInitByFile(File file, int with, int height) throws Exception {
        FileInputStream inputStream = new FileInputStream(file);
        BufferedImage canvas = ImageIO.read(inputStream);
        canvas = changeSize(canvas, with, height);
        return canvas;
    }

    /**
     * 画布初始化输入流
     *
     * @param inputStream 输入流
     * @param with        背景图宽度
     * @param height      背景图高度
     * @return canvas
     * @throws Exception
     */
    public static BufferedImage drawInitByInputStream(InputStream inputStream, int with, int height) throws Exception {
        BufferedImage canvas = ImageIO.read(inputStream);
        canvas = changeSize(canvas, with, height);
        return canvas;
    }

    /**
     * 对图片进行强制放大或缩小
     *
     * @param originalImage 原始图片
     * @return canvas
     */
    public static BufferedImage changeSize(BufferedImage originalImage, int width, int height) {
        BufferedImage image = new BufferedImage(width, height, originalImage.getType());
        Graphics2D g2d = image.createGraphics();
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.OPAQUE);
        g2d = image.createGraphics();
        g2d.drawImage(originalImage, 0, 0, width, height, null);
        g2d.dispose();
        return image;
    }

    /**
     * 绘制图片.
     *
     * @param canvas 画布
     * @param image  图片
     * @param imageX 图片横坐标
     * @param imageY 图片纵坐标
     * @return canvas
     */
    public static BufferedImage drawExtraImage(BufferedImage canvas, BufferedImage image, int imageX, int imageY) {
        Graphics2D g2d = canvas.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.drawImage(image, imageX, imageY, null);
        g2d.dispose();
        return canvas;
    }

    /**
     * 传入的图像必须是正方形的 才会 圆形 如果是长方形的比例则会变成椭圆的
     *
     * @return
     * @throws IOException
     */
    public static BufferedImage convertCircular(BufferedImage image) throws IOException {
        // 透明底的图片
        BufferedImage bi2 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, image.getWidth(), image.getHeight());
        Graphics2D g2 = bi2.createGraphics();
        g2.setClip(shape);
        // 使用 setRenderingHint 设置抗锯齿
        g2.drawImage(image, 0, 0, null);
        // 设置颜色
        g2.setBackground(Color.green);
        g2.dispose();
        return bi2;
    }

    /**
     * 保存图片.
     *
     * @param canvas  画布
     * @param type    图片类型
     * @param urlPath 路径
     * @return string
     * @throws Exception
     */
    public static void save(BufferedImage canvas, String type, String urlPath) throws Exception {
        ImageIO.write(canvas, type, new File(urlPath));
    }

    /**
     * 绘制一个图和一个文字框.文字居中
     *
     * @param canvas      画布
     * @param color       颜色
     * @param words       文字
     * @param wordsY      文字纵坐标
     * @param wordsWith   文字宽度
     * @param wordsHeight 文字高度
     * @param font        字体
     * @param fontSize    字体大小
     * @return g2d
     */
    public static BufferedImage drawWords(BufferedImage canvas, Integer color, String words, int wordsY, int wordsWith, int wordsHeight, String font, int fontSize) {
        Integer width = Integer.valueOf(new BigDecimal(canvas.getWidth()).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
        Graphics2D g2d = canvas.createGraphics();
        g2d.setColor(new Color(color));
        g2d.getDeviceConfiguration().createCompatibleImage(wordsWith, wordsHeight, Transparency.TRANSLUCENT);
        Font font1 = new Font(font, Font.PLAIN, fontSize);
        g2d.setFont(font1);
        FontMetrics fm = g2d.getFontMetrics(font1);
        int textWidth = fm.stringWidth(words);
        g2d.drawString(words, (width - textWidth) / 2, wordsY);
        return canvas;
    }

    /**
     * 绘制一个图和一个文字框
     *
     * @param canvas      画布
     * @param color       颜色
     * @param words       文字
     * @param wordsY      文字横坐标
     * @param wordsY      文字纵坐标
     * @param wordsWith   文字宽度
     * @param wordsHeight 文字高度
     * @param font        字体
     * @param fontSize    字体大小
     * @return g2d
     */
    public static BufferedImage drawWords(BufferedImage canvas, Integer color, String words, int wordsX, int wordsY, int wordsWith, int wordsHeight, String font, int fontSize) {
        Graphics2D g2d = canvas.createGraphics();
        g2d.setColor(new Color(color));
        g2d.getDeviceConfiguration().createCompatibleImage(wordsWith, wordsHeight, Transparency.TRANSLUCENT);
        Font font1 = new Font(font, Font.PLAIN, fontSize);
        g2d.setFont(font1);
        g2d.drawString(words, wordsX, wordsY);
        return canvas;
    }

    /**
     * 绘制一个图和一个文字框
     *
     * @param canvas      画布
     * @param color       颜色
     * @param words       文字
     * @param wordsY      文字横坐标
     * @param wordsY      文字纵坐标
     * @param wordsWith   文字宽度
     * @param wordsHeight 文字高度
     * @param font        字体
     * @param fontSize    字体大小
     * @return g2d
     */
    public static BufferedImage drawWords(BufferedImage canvas, Integer color, String words, int wordsX, int wordsY, int wordsWith, int wordsHeight, Font font, int fontSize) {
        Graphics2D g2d = canvas.createGraphics();
        g2d.setColor(new Color(color));
        g2d.getDeviceConfiguration().createCompatibleImage(wordsWith, wordsHeight, Transparency.TRANSLUCENT);
        g2d.setFont(font);
        g2d.drawString(words, wordsX, wordsY);
        return canvas;
    }

    /**
     * 判断是否含有特殊字符
     *
     * @param codePoint
     * @return
     */
    public static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) ||
                (codePoint == 0x9) ||
                (codePoint == 0xA) ||
                (codePoint == 0xD) ||
                ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
                ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    /**
     * 字符串转unicode
     *
     * @param str
     * @return
     */
    public static String stringToUnicode(String str) {
        StringBuffer sb = new StringBuffer();
        char[] c = str.toCharArray();
        for (int i = 0; i < c.length; i++) {
            sb.append("\\u" + Integer.toHexString(c[i]));
        }
        return sb.toString();
    }
}
